from IPython.display import clear_output
import factors
import inspect
n = 0
regression=False; N = 0 # run particular factor/ regression
for name, obj in inspect.getmembers(factors, predicate=inspect.isclass):
if obj.__module__ == "factors":
if n==N or regression==True:
clear_output(wait=False)
%run -i backtest.py {name}
factor_name = name
n = n+1
factor analysis begin: Factor0_Random 2024-02-23 02:24:00.305823
analysis factor/portfolio: True/True
long-short/group neutral: True/False
strategy: eq_weight optimize: max_sharpe
simulation_time: 0
start 2014-01-01
end 2017-01-01
use_storage_data: True
Dropped 18.1% entries from factor data: 18.1% in forward returns computation and 0.0% in binning phase (set max_loss=0 to see potentially suppressed Exceptions).
max_loss is 50.0%, not exceeded: OK!
factors: (756000, 2)
prices: (756, 1655)
pf_returns: (1086,)
pf_positions: (1086, 507)
pf_transactions: (2199, 8)
pf_benchmark: (1080,)
Quantiles Statistics
| min | max | mean | std | count | count % | |
|---|---|---|---|---|---|---|
| factor_quantile | ||||||
| 1 | 1.0 | 635.0 | 269.319560 | 173.653639 | 124149 | 20.047799 |
| 2 | 528.0 | 1234.0 | 856.992474 | 170.550635 | 123708 | 19.976585 |
| 3 | 1054.0 | 1860.0 | 1459.461475 | 177.464277 | 123699 | 19.975132 |
| 4 | 1577.0 | 2523.0 | 2044.316366 | 203.111005 | 123708 | 19.976585 |
| 5 | 2145.0 | 3139.0 | 2673.117531 | 214.071579 | 124001 | 20.023899 |
Returns Analysis
| 1D | 5D | 10D | |
|---|---|---|---|
| Ann. alpha | -0.008 | -0.016 | -0.017 |
| beta | 0.026 | 0.016 | 0.014 |
| Mean Period Wise Return Top Quantile (bps) | -0.098 | -0.222 | -0.243 |
| Mean Period Wise Return Bottom Quantile (bps) | 0.639 | 1.456 | 1.603 |
| Mean Period Wise Spread (bps) | -0.737 | -1.654 | -1.817 |
<Figure size 432x288 with 0 Axes>
Information Analysis
| 1D | 5D | 10D | |
|---|---|---|---|
| IC Mean | -0.002 | -0.004 | -0.005 |
| IC Std. | 0.037 | 0.038 | 0.039 |
| Risk-Adjusted IC | -0.046 | -0.111 | -0.115 |
| t-stat(IC) | -1.268 | -3.038 | -3.148 |
| p-value(IC) | 0.205 | 0.002 | 0.002 |
| IC Skew | 0.000 | 0.113 | 0.004 |
| IC Kurtosis | -0.326 | -0.058 | -0.511 |
Turnover Analysis
| 10D | 1D | 5D | |
|---|---|---|---|
| Quantile 1 Mean Turnover | 0.030 | 0.007 | 0.017 |
| Quantile 2 Mean Turnover | 0.038 | 0.009 | 0.023 |
| Quantile 3 Mean Turnover | 0.040 | 0.010 | 0.024 |
| Quantile 4 Mean Turnover | 0.043 | 0.010 | 0.025 |
| Quantile 5 Mean Turnover | 0.032 | 0.007 | 0.018 |
| 1D | 5D | 10D | |
|---|---|---|---|
| Mean Factor Rank Autocorrelation | 1.0 | 1.0 | 1.0 |
<Figure size 432x288 with 0 Axes>
Entire data start date: 2014-01-03 Entire data end date: 2016-12-22 Backtest months: 51
| Backtest | |
|---|---|
| Annual return | -1.5% |
| Cumulative returns | -6.2% |
| Annual volatility | 0.9% |
| Sharpe ratio | -1.72 |
| Calmar ratio | -0.21 |
| Stability | 0.84 |
| Max drawdown | -7.2% |
| Omega ratio | 0.63 |
| Sortino ratio | -1.93 |
| Skew | -5.46 |
| Kurtosis | 61.24 |
| Tail ratio | 0.75 |
| Daily value at risk | -0.1% |
| Gross leverage | 0.71 |
| Daily turnover | 0.3% |
| Alpha | -0.01 |
| Beta | 0.00 |
| Worst drawdown periods | Net drawdown in % | Peak date | Valley date | Recovery date | Duration |
|---|---|---|---|---|---|
| 0 | 7.18 | 2014-10-16 | 2016-02-24 | NaT | NaN |
| 1 | 1.07 | 2014-02-02 | 2014-05-22 | 2014-09-11 | 159 |
| 2 | 0.19 | 2014-01-05 | 2014-01-13 | 2014-01-17 | 10 |
| 3 | 0.08 | 2014-09-17 | 2014-09-29 | 2014-10-06 | 14 |
| 4 | 0.00 | 2014-01-28 | 2014-01-29 | 2014-01-30 | 3 |
| Stress Events | mean | min | max |
|---|---|---|---|
| Apr14 | -0.00% | -0.05% | 0.05% |
| Oct14 | -0.02% | -0.11% | 0.03% |
| Fall2015 | -0.05% | -0.72% | 0.02% |
| New Normal | -0.01% | -0.72% | 0.16% |
In-sample months: 47 Out-of-sample months: 3
| All | In-sample | Out-of-sample | |
|---|---|---|---|
| Annual return | -1.5% | -1.4% | -2.5% |
| Cumulative returns | -6.2% | -5.5% | -0.7% |
| Annual volatility | 0.9% | 0.9% | 0.5% |
| Sharpe ratio | -1.73 | -1.60 | -5.41 |
| Calmar ratio | -0.21 | -0.20 | -3.02 |
| Stability | 0.84 | 0.83 | 0.75 |
| Max drawdown | -7.2% | -7.2% | -0.8% |
| Omega ratio | 0.63 | 0.65 | 0.39 |
| Sortino ratio | -1.93 | -1.79 | -5.93 |
| Skew | -5.45 | -5.42 | 0.01 |
| Kurtosis | 60.99 | 59.06 | -0.42 |
| Tail ratio | 0.75 | 0.73 | 0.79 |
| Daily value at risk | -0.1% | -0.1% | -0.1% |
| Gross leverage | 0.71 | 0.71 | 0.73 |
| Daily turnover | 0.3% | 0.3% | 0.3% |
| Alpha | -0.01 | -0.01 | -0.02 |
| Beta | 0.00 | 0.00 | -0.02 |
Analysis: done
from IPython.display import Javascript
from nbconvert import HTMLExporter
def save_notebook():
display(
Javascript("IPython.notebook.save_notebook()"),
include=['application/javascript']
)
def output_HTML(current_file, output_file):
import codecs
import nbformat
exporter = HTMLExporter()
output_notebook = nbformat.read(current_file, as_version=4)
output, resources = exporter.from_notebook_node(output_notebook)
file = codecs.open(output_file, 'w', encoding='utf-8')
file.write(output)
file.close()
print('saved: ', factor_name)
current_file = 'regression.ipynb'
output_file = f'results/factor_{factor_name}.html'
output_HTML(current_file, output_file)
saved: Factor0_Random